import json
import mimetypes
import os.path
import platform

import allure
import requests
import curlify
from jsonpath_ng import parse
from utils.yamltool import writeYaml, YamlReader, BasePath

if platform.system() == 'Linux':
	# 添加新的 MIME 类型
	mimetypes.add_type('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', '.xlsx')


def send_request(params):
	params = replace_func(params)
	# 处理文件上传
	files = params.get('files')
	if files is not None:
		fileType, _ = mimetypes.guess_type(files)
		_, fileName = os.path.split(files)
		with open(files, 'rb') as f:
			files = {'file': (fileName, f.read(), fileType)}
		formData = params.get('form')
		formData['Expires'] = formData.get('expires')
		formData['OSSAccessKeyId'] = formData.get('accessKeyId')
		formData['Signature'] = formData.get('signature')
		formData['path'] = formData.get('dir')
		formData.pop('expires')
		formData.pop('accessKeyId')
		formData.pop('signature')
		formData.pop('dir')

	response = requests.request(method=params.get("method"), url=params.get("url"), headers=params.get("headers"),
	                            files=files, data=params.get('form'), params=params.get("data"),
	                            json=params.get("data"))

	allure.attach(str(params), f'测试用例', allure.attachment_type.TEXT)
	allure.attach(str(params.get('url')), f'请求URL: {params.get('url')}', allure.attachment_type.TEXT)
	allure.attach(str(params.get('headers')), f'请求头', allure.attachment_type.TEXT)
	allure.attach(str(params.get('method')), f'请求方法: {params.get('method')}', allure.attachment_type.TEXT)
	allure.attach(str(params.get('data') if params.get('data') else params.get('form')), f'请求参数',
	              allure.attachment_type.TEXT)
	allure.attach(str(response.status_code), f'响应码: {response.status_code}', allure.attachment_type.TEXT)
	allure.attach(str(response.text), f'接口响应', allure.attachment_type.TEXT)
	allure.attach(str(params.get('expected')), f'预期结果', allure.attachment_type.TEXT)
	if files is None:
		allure.attach(str(curlify.to_curl(response.request)), f'cURL'), allure.attachment_type.TEXT
	else:
		allure.attach(str(params.get('files')), f'上传文件源文件', allure.attachment_type.TEXT)

	# 提取数据
	extract = params.get('extract')
	if isinstance(extract, dict) and extract is not None:
		extract_data(extract, json.loads(response.text.replace('\'', '"')))
	elif isinstance(extract, str) and extract != '':
		extract = json.loads(extract.replace('\'', '"'))
		extract_data(extract, json.loads(response.text.replace('\'', '"')))
	return response


# 替换用例中的函数
def replace_func(params):
	for key, value in params.items():
		if isinstance(value, str) and value.startswith('${') and value.endswith('}'):
			params[key] = eval(value[value.index('{') + 1:value.index('}')])

	parm, key1 = extract_func(params)
	for key, value in parm.items():
		if isinstance(value, str) and value.startswith('${') and value.endswith('}'):
			params[key1][key] = eval(value[value.index('{') + 1:value.index('}')])
		elif isinstance(value, dict):
			for k, v in value.items():
				params[key1][key][k] = eval(v[v.index('{') + 1:v.index('}')])
	return params


# 提取函数
def extract_func(extract, k=None):
	for key, value in extract.items():
		if isinstance(value, dict) and value is not None:
			extract = value
			k = key
			extract_func(extract, key)
	return extract, k


# 提取数据
def extract_data(extract, response):
	"""
	提取接口返回数据
	:param extract: 提取的key
	:param response: 接口返回
	:return:
	"""
	for key, value in extract.items():
		data = []
		for v in parse(value).find(response):
			data.append(v.value)

		if len(data) == 1:
			writeYaml.set(key, data[0])
			allure.attach(str({key: data[0]}), f'提取数据'), allure.attachment_type.TEXT
		elif len(data) > 1:
			writeYaml.set(key, data)
			allure.attach(str({key: data}), f'提取数据'), allure.attachment_type.TEXT


def get_depend_data(key):
	return YamlReader(os.path.join(BasePath, 'data', 'extract.yaml')).get(key)
